package zwyarraylist;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 * 扩容机制
 * 
 * @ClassName: ArrayList03Test
 * @Description: TODO
 * @author zhaoweiyong yyd
 * @date 2017年6月23日 下午3:12:05 *
 */
public class ArrayList03Test {

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
	}

	/**
	 * 起始行号：203行 public void ensureCapacity(int minCapacity) { int minExpand =
	 * (elementData != EMPTY_ELEMENTDATA) // any size if real element table ? 0
	 * // larger than default for empty table. It's already supposed to be // at
	 * default size. : DEFAULT_CAPACITY;
	 * 
	 * if (minCapacity > minExpand) { ensureExplicitCapacity(minCapacity); } }
	 * 
	 * @throws SecurityException
	 * @throws NoSuchFieldException
	 * @title: test
	 * @Author: zhaoweiyong
	 * @Date: 2017年6月23日下午3:12:11
	 */
	@Test
	public void testEnsureCapacity() throws Exception {
		ArrayList<String> dataList = new ArrayList<String>();
		Field elementDataField = dataList.getClass().getDeclaredField("elementData");
		elementDataField.setAccessible(true);
		Object[] elementData = (Object[]) elementDataField.get(dataList);
		System.out.println("初始数组的大小：" + elementData.length);
		// 第一次扩容到10
		// 接下来的10次是不扩容的
		dataList.add("1");
		elementData = (Object[]) elementDataField.get(dataList);
		System.out.println("第一次数组的大小：" + elementData.length);
		dataList.add("2");
		dataList.add("3");
		dataList.add("4");
		dataList.add("5");
		dataList.add("6");
		dataList.add("7");
		dataList.add("8");
		dataList.add("9");
		dataList.add("10");
		elementData = (Object[]) elementDataField.get(dataList);
		System.out.println("第10次数组的大小：" + elementData.length);

		// 当之前的容量不能容纳下新的元素
		// 如果添加进去后需要的容量 < 之前容量的1.5倍则扩充为1.5倍后的容量
		dataList.add("11");
		elementData = (Object[]) elementDataField.get(dataList);
		System.out.println("第11次数组的大小：" + elementData.length);
		dataList.add("12");
		dataList.add("13");
		dataList.add("14");
		dataList.add("15");
		dataList.add("16");
		elementData = (Object[]) elementDataField.get(dataList);
		Assert.assertEquals((15 >> 1) + 15, elementData.length);
		elementData = (Object[]) elementDataField.get(dataList);
		System.out.println("第16次数组的大小：" + elementData.length);

		dataList.ensureCapacity(23);
		elementData = (Object[]) elementDataField.get(dataList);
		Assert.assertEquals((22 >> 1) + 22, elementData.length);
		System.out.println("第23次数组的大小：" + elementData.length);

		// 当添加第34个元素的时候，扩容到49
		dataList.ensureCapacity(34);
		elementData = (Object[]) elementDataField.get(dataList);
		Assert.assertEquals((33 >> 1) + 33, elementData.length);
		System.out.println("第34次数组的大小：" + elementData.length);

		dataList.ensureCapacity(100);
		elementData = (Object[]) elementDataField.get(dataList);
		int a = (49 >> 1) + 49;
		Assert.assertEquals(a > 100 ? a : 100, elementData.length);
		System.out.println("addAll之类的扩容：" + elementData.length);
		dataList.ensureCapacity(Integer.MAX_VALUE - 8);
		elementData = (Object[]) elementDataField.get(dataList);
		//java.lang.OutOfMemoryError: Java heap space
		//堆空间不足
		System.out.println("极限测试：" + elementData.length);
	}
	
	/**
	* 测试堆栈
	* @title: testHeapSpace 
	* @Author: zhaoweiyong
	* @Date: 2017年6月30日下午8:33:56
	 */
	//java.lang.OutOfMemoryError: Java heap space
	//13845149
	@Test
	public void testHeapSpace(){
		List<String> maxList = new ArrayList<>();
		for(int i = 0; i<Integer.MAX_VALUE; i++){
			maxList.add(UUID.randomUUID().toString());
			System.out.println(i);
		}
		System.out.println(maxList.size());
	}

}
